/**
 * @name 表单验证器
 * @author Conan
 * @version 1.0
 * 
 * // 自定义验证方法
 * const validatePass = (value, callback) => {
 *   if (value === '') {
        callback('请输入密码');
      } else {
        callback();
      }
 * }
 * 
 * required: 必填验证(true:必填)
 * regular: 正则表达式验证(正则表达式方法)
 * validator: 自定义验证规则验证(todo 暂不支持异步校验)
 * 
 * rules: {
 *    field1: [
 *      { required: true, message: '错误消息提示'}
 *    ],
 *    field1: [
 *      { regular: validURL, message: '错误消息提示'}
 *    ],
 *    field2: [
 *      { validator: validatePass, message: '错误消息提示'}
 *    ],
 *    field3: [
 *      { regular: validURL, message: '错误消息提示'},
 *      { validator: validatePass, message: '错误消息提示'}
 *    ]
 * }
 * 
 * data: {
 *  field1: 'value',
 *  field2: 'value',
 *  field3: 'value'
 * }
 */


/**
 * 验证器核心方法(暴露方法)
 * @param {*} rules 验证规则对象
 * @param {*} data 验证数据对象
 * @returns 
 */
function validateRule(rules, data) {
  return new Promise((resolve, reject) => {
    if(!rules) {
      reject(new Error('验证规则对象不能为空'))
    }
    if(!data) {
      reject(new Error('验证目标对象能为空'))
    }

    const errObj = {}
    for (let key in rules) {
      if (data.hasOwnProperty(key)) {
        const value = data[key]
        const ruleList = rules[key]

        ruleList.forEach(item => {
          if (item.hasOwnProperty('required') && item.required) { // 必填验证
            
            let requiredResult = _notEmpty(item, data, key)
            if (!requiredResult.pass) {
              errObj[key] ? errObj[key].push(requiredResult.result) : errObj[key] = [requiredResult.result]
            }

          } else if (item.hasOwnProperty('regular')) { // 正则表达式验证

            let regularResult = _regularValidate(item, data, key)
            if (!regularResult.pass) {
              errObj[key] ? errObj[key].push(regularResult.result) : errObj[key] = [regularResult.result]
            }

          } else if (item.hasOwnProperty('validator')) { // 自定义规则验证

            let validatorResult = _customizeValidator(item, data, key)
            if (!validatorResult.pass) {
              errObj[key] ? errObj[key].push(validatorResult.result) : errObj[key] = [validatorResult.result]
            }

          }

        })
      }
    }

    if (Object.keys(errObj).length > 0) {
      resolve({
        valid: false,
        errObj
      })
    } else {
      resolve({
        valid: true,
        errObj: {}
      })
    }
  })
}








// ---------------------------------------------------------------------- start 单独的验证方法
/**
 * 正在表达式验证
 * @param {*} rule 验证规则对象
 * @param {*} data 验证数据对象
 * @param {*} data 验证字段
 * @returns {
 *  pass: true: 验证通过; false: 验证不通过
 *  message: 错误消息提示
 * }
 */
function _regularValidate(rule, data, field) {
  let reg = rule.regular(data[field])
  return {
    pass: reg,
    result: {
      field: field,
      message: rule.message || '验证不通过'
    }
  }
}

/**
 * 自定义验证器
 * @param {*} rule 验证规则对象
 * @param {*} data 验证数据对象
 * @param {*} data 验证字段
 * @returns {
 *  pass: true: 验证通过; false: 验证不通过
 *  message: 错误消息提示
 * }
 */
function _customizeValidator(rule, data, field) {
  let validator = rule.validator

  let pass = true
  let message = ''
  validator(data[field], (value) => {
    if (value) {
      pass = false
      message = value
    }
  })

  return {
    pass,
    result: {
      field: field,
      message: rule.message || message
    }
  }
}

/**
 * 必填验证
 * @param {*} value
 * @returns {
 *  pass: true: 验证通过; false: 验证不通过
 *  message: 错误消息提示
 * }
 */
function _notEmpty(rule, data, field) {
	const reg = /\S/; // 不为空
  return {
    pass: reg.test(data[field]),
    result: {
      field: field,
      message: rule.message || `${field} 字段不能为空`
    }
  }
}
// ---------------------------------------------------------------------- end 单独的验证方法


// todo 模块化使用时可以用 export 进行输入核心方法以及其它方法
// export {
//   validateRule
// }